package com.amt.util;

import com.amt.configure.FileUploadResponse;
import com.amt.configure.Upload;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Title: FileUploadUtil.java
 * @Package com.amt.util
 * @Description: TODO(文件上传工具类)
 * @author 江伟
 * @date 2021年3月21日 下午3:07:03 Copyright (c) ©1994-2021 Scjydz.com All Rights
 *       Reserved.
 */
@Api(tags = "文件上传服务API")
@RestController
@RequestMapping("gpzfb/file")
@Slf4j
public class FileUploadUtil {

	@Autowired
	private Upload upload;

	// 文件格式白名单
	private String whiteFileType = ".+(doc|docx|xls|xlsx|zip|rar|jpg|png|jpeg|gif|JPEG|JPG|PNG|mp3|ttf)$";

	@ApiOperation(value = "多个文件上传")
	@RequestMapping(value = "/uploadListFile", method = RequestMethod.POST)
	@ResponseBody
	public List<FileUploadResponse> uploadListFile(@RequestParam("file") MultipartFile[] files,
			HttpServletRequest request) {
		List<FileUploadResponse> list = new ArrayList<FileUploadResponse>();
		// 获取文件存放根路径
		String basePath = upload.getBasePath();
		// 文件存放分支路径
		String location = DateUtil.format(new Date(), "yyyy-MM-dd") + "/";
		// 文件类型
		String contentType = null;
		// 原文件名称
		String fileName = null;
		// 存放名称
		String saveName = null;
		// 图片后缀
		String imgSuffix = null;
		// 判断文件夹是否存在，不存在则
		File targetFile = new File(basePath + location);
		if (!targetFile.exists()) {
			targetFile.setWritable(true, false);
			targetFile.mkdirs();
		}
		for (MultipartFile file : files) {
			FileUploadResponse rs = new FileUploadResponse();
			fileName = file.getOriginalFilename();
			imgSuffix = fileName.substring(fileName.lastIndexOf("."));
			Matcher matcher = Pattern.compile(whiteFileType).matcher(imgSuffix);
			if (matcher.find()) { // 验证文件格式
				contentType = file.getContentType();
				saveName = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase() + imgSuffix;
				try {
					// COPY_ATTRIBUTES 将源文件的文件属性信息复制到目标文件中
					// REPLACE_EXISTING 替换已存在的文件
					Files.copy(file.getInputStream(), Paths.get(upload.getBasePath() + location, saveName),
							StandardCopyOption.REPLACE_EXISTING);
					rs.setContentType(contentType);
					rs.setFileName(fileName);
					rs.setDecryptUrl(upload.getFileAccessPrefix() + location + saveName);
					rs.setUrl(Base64Util.encodeData(location + saveName));
					rs.setStatus(200);
				} catch (Exception e) {
					rs.setStatus(201);
					rs.setMessage("文件上传失败！");
					log.error("上传文件失败，{}", e);
				}
			} else {
				log.error("非法的文件格式，{}", fileName);
				rs.setStatus(201);
				rs.setMessage("非法的文件格式！");
			}
			list.add(rs);
		}
		return list;

	}

	@ApiOperation(value = "单个文件上传")
	@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
	@ResponseBody
	public FileUploadResponse uploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
		FileUploadResponse rs = new FileUploadResponse();
		// 获取文件存放根路径
		String basePath = upload.getBasePath();
		// 文件存放分支路径
		String location = DateUtil.format(new Date(), "yyyy-MM-dd") + "/";
		// 文件类型
		String contentType = null;
		// 原文件名称
		String fileName = null;
		// 存放名称
		String saveName = null;
		// 图片后缀
		String imgSuffix = null;
		// 判断文件夹是否存在，不存在则
		File targetFile = new File(basePath + location);
		if (!targetFile.exists()) {
			targetFile.setWritable(true, false);
			targetFile.mkdirs();
		}

		fileName = file.getOriginalFilename();
		imgSuffix = fileName.substring(fileName.lastIndexOf("."));
		Matcher matcher = Pattern.compile(whiteFileType).matcher(imgSuffix);
		if (matcher.find()) { // 验证文件格式
			contentType = file.getContentType();
			saveName = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase() + imgSuffix;
			try {
				// COPY_ATTRIBUTES 将源文件的文件属性信息复制到目标文件中
				// REPLACE_EXISTING 替换已存在的文件
				Files.copy(file.getInputStream(), Paths.get(upload.getBasePath() + location, saveName),
						StandardCopyOption.REPLACE_EXISTING);
				rs.setContentType(contentType);
				rs.setFileName(fileName);
				rs.setDecryptUrl(upload.getFileAccessPrefix() + location + saveName);
				rs.setUrl(Base64Util.encodeData(location + saveName));
				rs.setStatus(200);
			} catch (Exception e) {
				rs.setStatus(201);
				rs.setMessage("文件上传失败！");
				log.error("上传文件失败，{}", e);
			}

		} else {
			log.error("非法的文件格式，{}", fileName);
			rs.setStatus(201);
			rs.setMessage("非法的文件格式！");
		}
		return rs;

	}

	@ApiOperation(value = "小程序文件上传")
	@RequestMapping(value = "/miniUploadFile", method = RequestMethod.POST)
	@ResponseBody
	public FileUploadResponse miniUploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
		FileUploadResponse rs = new FileUploadResponse();
		// 获取文件存放根路径
		String basePath = upload.getBasePath();
		// 文件存放分支路径
		String location = DateUtil.format(new Date(), "yyyy-MM-dd") + "/";
		// 文件类型
		String contentType = null;
		// 原文件名称
		String fileName = null;
		// 存放名称
		String saveName = null;
		// 图片后缀
		String imgSuffix = null;
		// 判断文件夹是否存在，不存在则
		File targetFile = new File(basePath + location);
		if (!targetFile.exists()) {
			targetFile.setWritable(true, false);
			targetFile.mkdirs();
		}

		fileName = file.getOriginalFilename();
		imgSuffix = fileName.substring(fileName.lastIndexOf("."));
		Matcher matcher = Pattern.compile(whiteFileType).matcher(imgSuffix);
		if (matcher.find()) { // 验证文件格式
			contentType = file.getContentType();
			saveName = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase() + imgSuffix;
			try {
				// COPY_ATTRIBUTES 将源文件的文件属性信息复制到目标文件中
				// REPLACE_EXISTING 替换已存在的文件
				Files.copy(file.getInputStream(), Paths.get(upload.getBasePath() + location, saveName),
						StandardCopyOption.REPLACE_EXISTING);
				rs.setContentType(contentType);
				rs.setFileName(fileName);
				rs.setDecryptUrl(upload.getFileAccessPrefix() + location + saveName);
				rs.setUrl(Base64Util.encodeData(location + saveName));
				rs.setStatus(200);
			} catch (Exception e) {
				rs.setStatus(201);
				rs.setMessage("文件上传失败！");
				log.error("上传文件失败，{}", e);
			}

		} else {
			log.error("非法的文件格式，{}", fileName);
			rs.setStatus(201);
			rs.setMessage("非法的文件格式！");
		}
		return rs;

	}


	@ApiOperation(value = "单个身份证图片文件上传")
	@RequestMapping(value = "/uploadCardFile", method = RequestMethod.POST)
	@ResponseBody
	public FileUploadResponse uploadCardFile(@RequestParam("file") MultipartFile  file, HttpServletRequest request) {
		FileUploadResponse rs = new FileUploadResponse();
		// 获取文件存放根路径
		String basePath = upload.getBasePath();
		// 文件存放分支路径
		String location = DateUtil.format(new Date(), "yyyy-MM-dd") + "/";
		// 文件类型
		String contentType = null;
		// 原文件名称
		String fileName = null;
		// 存放名称
		String saveName = null;
		// 图片后缀
		String imgSuffix = null;
		// 判断文件夹是否存在，不存在则
		File targetFile = new File(basePath + location);
		if(!targetFile.exists()){
			targetFile.setWritable(true, false);
			targetFile.mkdirs();
		}

		fileName = file.getOriginalFilename();
		imgSuffix = fileName.substring(fileName.lastIndexOf("."));
		Matcher matcher = Pattern.compile(whiteFileType).matcher(imgSuffix);
		if(matcher.find()) { // 验证文件格式
			contentType = file.getContentType();
			//以card打头
			saveName = "card_"+UUID.randomUUID().toString().replaceAll("-", "").toUpperCase() + imgSuffix;
			try {
				// java7中新增特性
				// ATOMIC_MOVE 原子性的复制
				// COPY_ATTRIBUTES 将源文件的文件属性信息复制到目标文件中
				// REPLACE_EXISTING 替换已存在的文件
				Files.copy(file.getInputStream(), Paths.get(upload.getBasePath() + location, saveName),
						   StandardCopyOption.REPLACE_EXISTING);
				rs.setContentType(contentType);
				rs.setFileName(fileName);
				rs.setDecryptUrl(upload.getFileAccessPrefix() + location + saveName);
				rs.setUrl(Base64Util.encodeData(location + saveName));
				rs.setStatus(200);
			} catch (Exception e) {
				rs.setStatus(201);
				rs.setMessage("文件上传失败！");
				log.error("上传文件失败，{}" , e);
			}

		} else {
			log.error("非法的文件格式，{}",imgSuffix);
			rs.setStatus(201);
			rs.setMessage("非法的文件格式！");
		}
		return rs;

	}

}
